/*
 * Copyright (c) 2019. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * www.mfhcd.com
 */

package cn.starremote.component.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;


/**
 * @ClassName: DateUtil 
 * @Description: 日期时间处理类
 * @author Wangjw
 * @version	1.0
 */
@Slf4j
public class DateUtil {

	public static final String DEFAULT_TIME_FORMAT_DB = "yyyyMMddHHmmss";
	public static final String DEFAULT_TIME_FORMAT_YYYYMMDD = "yyyyMMdd";
	public static final String DEFAULT_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String DEFAULT_TIME_FORMAT_US = "EEE MMM dd HH:mm:ss z yyyy";
	public static final String DEFAULT_TIME_FORMAT_YYYY_MM_DD = "yyyy-MM-dd";
	public static final String DEFAULT_TIME_FORMAT_YYYY_M_D = "yyyy.m.d";
	/**
	 * @Title: getCurrentDateString 
	 * @Description: 得到当前日期字符串:yyyymmdd
	 * @return String:yyyyMMdd
	 * @throws 
	*/ 
	public static String getCurrentDateString() {
		Calendar calendar = Calendar.getInstance();
		int month = calendar.get(Calendar.MONTH) + 1;
		int date = calendar.get(Calendar.DATE);
		return "" + calendar.get(Calendar.YEAR)
				+ (month < 10 ? "0" + month : "" + month)
				+ (date < 10 ? "0" + date : "" + date);
	}

	/**
	 * @Title: getCurrentDateInteger
	 * @Description: 得到当前日期 INTEGER数值:yyyymmdd
	 * @return INTEGER数值:yyyyMMdd
	 * @throws
	 */
	public static Integer getCurrentDateInteger() {
		return Integer.valueOf(getCurrentDateString());
	}
	/** 
	 * @Title: getCurrentDateTimeString 
	 * @Description: 得到当前日期字符串:yyyyMMddHHmmss
	 * @return String:yyyyMMddHHmmss
	 * @throws 
	*/ 
	public static String getCurrentDateTimeString() {
		return getDifferentTime(0);
	}

	/**
     * 格式化日期yyyy-MM-dd
     */
    public static String formatDate(String date) {
    	String d1 = date;
    	SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
    	Date date2 = null;
    	try {
    		date2 = format.parse(d1);
    	} catch (ParseException e) {
			throw new RuntimeException(e);
    	}
    	SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd");
    	String newD = format1.format(date2);
    	return newD;
    }
	
	/**
	 * 获取制定格式的日期
	 * 
	 * @param format yyyyMMddHHmmss
	 * 				 yyyy
	 * 				 ddHHmm
	 *            
	 * @return String
	 */
	public static  String getDifferentTimeByFormat( String format )
	{
		GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance();
		SimpleDateFormat formatter = new SimpleDateFormat( format );
		return formatter.format( calendar.getTime() );
	}
	
	/** 
	 * @Title: getCurrentDate
	 * @Description: 得到当前日期字符串,适用于数据库为Date类型，yyyyMMddHHmmss
	 * @return Date:yyyyMMddHHmmss
	 * @throws 
	*/ 
	public static Date getCurrentDate() {
		return new Date();
	}

	// 判断两日期格式是否相等
	public static boolean isDateEqual(Date date1, Date date2) {

		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date1);
		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(date2);

		return (cal1.get(Calendar.YEAR) == cal2
				.get(Calendar.YEAR)
				&& cal1.get(Calendar.MONTH) == cal2
						.get(Calendar.MONTH) && cal1
					.get(Calendar.DAY_OF_MONTH) == cal2
				.get(Calendar.DAY_OF_MONTH));

	}



	// 将格式为“20060302”形式的字符串转换成日期类型yyyy-MM-dd
	public static Date getToDate(String s) {
		StringBuffer sb = new StringBuffer();
		sb.append(s.substring(0, 4)).append("-").append(s.substring(4, 6))
				.append("-").append(s.substring(6, 8));
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date obj = null;
		try {
			obj = sdf.parse(sb.toString());
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return obj;
	}

	// 将格式为“2006-02-23”的日期字符串转化为日期类型
	/**
	 * 将格式为“2006-02-23”的日期字符串转化为日期类型 格式为"2004-10-10" --> Date
	 * <p>
	 * <code> checkStartEndDate </code>
	 * </p>
	 *
	 * @author Songyi 2004-12-15
	 * @since 1.1
	 */
	public static Date getString2Date(String sDate) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date obj = null;

		try {
			obj = sdf.parse(sDate);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}

		return obj;
	}

	// 判断当前的字符串是否为当前日期
	public static boolean isCurrentDate(String strDate) {
		return strDate == null || !strDate.equals(getCurrentDateString()) ? false
				: true;
	}

	// 取当前日期前一天或后一天，up传true表示取当前的前一天，up传false表示取当前日期的后一天
	public static String rollDate(Date date, boolean up) {

		if (date == null)
			return null;

		GregorianCalendar beforeCalendar = new GregorianCalendar();
		beforeCalendar.setTime(date);
		beforeCalendar.add(Calendar.DATE, up ? +1 : -1);
		int beforeDate = beforeCalendar.get(Calendar.DATE);
		int beforeMonth = beforeCalendar.get(Calendar.MONTH) + 1;
		int beforeYear = beforeCalendar.get(Calendar.YEAR);

		return "" + beforeYear
				+ (beforeMonth < 10 ? "0" + beforeMonth : "" + beforeMonth)
				+ (beforeDate < 10 ? "0" + beforeDate : "" + beforeDate);

	}

	// 取当前日期前两天或后两天，up传true表示取当前的前两天，up传false表示取当前日期的后两天
	public static String twoDays(Date date, boolean up) {

		if (date == null)
			return null;

		GregorianCalendar beforeCalendar = new GregorianCalendar();
		beforeCalendar.setTime(date);
		beforeCalendar.add(Calendar.DATE, up ? +2 : -2);
		int beforeDate = beforeCalendar.get(Calendar.DATE);
		int beforeMonth = beforeCalendar.get(Calendar.MONTH) + 1;
		int beforeYear = beforeCalendar.get(Calendar.YEAR);

		return "" + beforeYear
				+ (beforeMonth < 10 ? "0" + beforeMonth : "" + beforeMonth)
				+ (beforeDate < 10 ? "0" + beforeDate : "" + beforeDate);

	}

	// 返回年月日方式或者年月日时分方式对应的日期时间
	/**
	 * @param str
	 * @return
	 */
	public static Date String2Date(String str) {
		try {
			SimpleDateFormat s1 = new SimpleDateFormat("yyyyMMdd");
			SimpleDateFormat s2 = new SimpleDateFormat("yyyyMMddHHmm");
			SimpleDateFormat s3 = new SimpleDateFormat("yyyyMMddHHmmss");

			if (str.length() == 8) {
				return s1.parse(str);
			} else if (str.length() == 12) {
				return s2.parse(str);
			} else if (str.length() == 14) {
				return s3.parse(str);
			} else {
				throw new RuntimeException("validation.date.parse_error");
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}

	// 比较2个日期：返回－1，1，0
	/**
	 * @param StartDate
	 * @param EndDate
	 * @return
	 */
	public static int DateCompare(String StartDate, String EndDate) {

		Date start = String2Date(StartDate);
		Date end = String2Date(EndDate);

		if (start.before(end)) {
			return -1;
		} else if (start.after(end)) {
			return 1;
		} else
			return 0;

	}

	// 比较2个时间：返回－1，1，0
	/**
	 * @param StartTime
	 * @param EndTime
	 * @return
	 */
	public static int TimeCompare(String StartTime, String EndTime) {

		if ((StartTime.length() != 4) || (EndTime.length() != 4)) {
			throw new RuntimeException("validation.time.parse_error");
		}
		int startHour = Integer.parseInt(StartTime.substring(0, 2));
		int startMin = Integer.parseInt(StartTime.substring(2, 4));
		int endHour = Integer.parseInt(EndTime.substring(0, 2));
		int endMin = Integer.parseInt(EndTime.substring(2, 4));

		if (startHour < endHour) {
			return -1;
		} else if (startHour > endHour) {
			return 1;
		} else {
			if (startMin < endMin) {
				return -1;
			} else if (startMin > endMin) {
				return 1;
			} else
				return 0;
		}

	}

	// 获得从now开始iMonth个月前的一天
	/**
	 * @param now
	 * @param iMonth
	 * @return
	 */
	public static Date getDateBefore(Date now, int iMonth) {

		Calendar c = Calendar.getInstance();
		c.setTime(now);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH);
		int day = c.get(Calendar.DAY_OF_MONTH);

		month = month - iMonth;
		if (month < 1) {
			month = month + 12;
			year = year - 1;
		}

		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, month);
		c.set(Calendar.DAY_OF_MONTH, day);

		return c.getTime();
	}

	// 获得从now开始iMonth个月后的一天
	/**
	 * @param now
	 * @param iMonth
	 * @return
	 */
	public static Date getDateAfter(Date now, int iMonth) {

		Calendar c = Calendar.getInstance();
		c.setTime(now);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH);
		int day = c.get(Calendar.DAY_OF_MONTH);

		month = month + iMonth;
		if (month > 12) {
			month = month - 12;
			year = year + 1;
		}

		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, month);
		c.set(Calendar.DAY_OF_MONTH, day);

		return c.getTime();
	}

	public static Date getLastDay(Date now) {

		Calendar c = Calendar.getInstance();
		c.setTime(now);
		int day = c.get(Calendar.DAY_OF_MONTH);
		c.set(Calendar.DAY_OF_MONTH, day - 1);

		return c.getTime();
	}

	// 得到当前日期的开始时间
	/**
	 * 得到当前日期的开始时间
	 *
	 * @param now
	 * @return
	 */
	public static Date getDayStart(Date now) {

		Calendar c = Calendar.getInstance();
		c.setTime(now);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);

		return c.getTime();
	}

	// 得到当前日期的结束时间
	/**
	 * 得到当前日期的结束时间
	 *
	 * @param now
	 * @return
	 */
	public static Date getDayEnd(Date now) {

		Calendar c = Calendar.getInstance();
		c.setTime(now);
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);

		return c.getTime();
	}

	// 判断输入的日期是否符合要求，1、3、5、7、8、10、12月日期不能大于31日，4、6、9、11月不能日期不能大于30日，2月平年不能大于28日，润年不能大于29日
	public static boolean isDateValid(String inStr) {
		int year, month, day;
		year = Integer.parseInt(inStr.substring(0, 4));
		if (inStr.indexOf(4) == '0') {
			month = Integer.parseInt(inStr.substring(5, 6));
		} else {
			month = Integer.parseInt(inStr.substring(4, 6));
		}
		if (inStr.indexOf(6) == '0') {
			day = Integer.parseInt(inStr.substring(7, 8));
		} else {
			day = Integer.parseInt(inStr.substring(6, 8));
		}

		if (month > 12 || day > 31 || month < 1 || day < 1)
			return false;

		if (month == 4 || month == 6 || month == 9 || month == 11) {
			if (day > 30)
				return false;
		}

		if (month == 2) {
			if (year % 4 == 0) {
				if (day > 29)
					return false;
			} else {
				if (day > 28)
					return false;
			}
		}

		return true;
	}

	/**
	 * 取得指定时间间隔后的系统时间
	 *
	 * @param hour
	 *            小时
	 * @return String
	 */
	public static  String getDifferentTime( int hour )
	{
		GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance();
		calendar.add( Calendar.HOUR, hour );
		SimpleDateFormat formatter = new SimpleDateFormat( DEFAULT_TIME_FORMAT_DB );
		return formatter.format( calendar.getTime() );
	}

	/**
	 * 取得指定时间间隔后的系统时间
	 *
	 * @param minutes
	 *
	 * @return String
	 */
	public static  String getDifferentTimeByMinute( int minutes )
	{
		GregorianCalendar calendar = (GregorianCalendar) Calendar.getInstance();
		calendar.add( Calendar.MINUTE, minutes);
		SimpleDateFormat formatter = new SimpleDateFormat( DEFAULT_TIME_FORMAT_DB );
		return formatter.format( calendar.getTime() );
	}

	public static String getDifferentTimeByMinute(String date1, int minutes,
			String format) {
		Calendar cal1 = Calendar.getInstance();
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		try {
			cal1.setTime(formatter.parse(date1));
			cal1.add(Calendar.MINUTE, minutes);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return formatter.format(cal1.getTime());
	}

	/**
	 * 取得若干天前/后的系统日期
	 *
	 * @param days
	 *            与现在相隔的日数，正数为当前日期之后，负数为当前日期之前
	 * @return String
	 */
	public static String getDifferentDate(int days) {
		return getDifferentTime(24 * days);
	}
	/**
	 * 比较日期时间
	 *
	 *
	 */
	public static int dateTimeCompare(String date1,String date2) {

		Calendar cal1 = Calendar.getInstance();
		Calendar cal2 = Calendar.getInstance();
		SimpleDateFormat formatter = new SimpleDateFormat( DEFAULT_TIME_FORMAT_DB );
		try {
			cal1.setTime(formatter.parse(date1));
			cal2.setTime(formatter.parse(date2));
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		int result=cal1.compareTo(cal2);
		return result;
	}

	/**
	 * 根据指定格式比较时间
	 *
	 *
	 */
	public static int dateTimeCompare(String date1, String date2, String format) {

		Calendar cal1 = Calendar.getInstance();
		Calendar cal2 = Calendar.getInstance();
		SimpleDateFormat formatter = new SimpleDateFormat(
				format);
		try {
			cal1.setTime(formatter.parse(date1));
			cal2.setTime(formatter.parse(date2));
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		int result = cal1.compareTo(cal2);
		return result;
	}

	/**
	  *
	  * @Title: parseDate
	  * @Description: 把字符串解析为日期
	  * @param dateStr
	  * @param format
	  * @return Date
	  */
	 public static Date parseDate(String dateStr, String format) {

	  Date date = null;
	  try {
	   DateFormat df = new SimpleDateFormat(format);
	   date = (Date) df.parse(dateStr);
	  } catch (Exception e) {
		  throw new RuntimeException(e);
	  }
	  return date;
	 }

	 /**
	  * @Title: format
	  * @Description: 把日期格式化输出为字符串
	  * @param date
	  * @param format
	  * @return String
	  */
	 public static String format(Date date, String format) {
	  String result = "";
	  try {
	   if (date != null) {
	    DateFormat df = new SimpleDateFormat(format);
	    result = df.format(date);
	   }
	  } catch (Exception e) {
		  throw new RuntimeException(e);
	  }
	  return result;
	 }


	/**
	 * 格式化日期yyyyMMddHHmmss
	 */
	public static String formatDateTime(String date) {
		DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
		Date dateTime= null;
		try {
			dateTime = df.parse(date);
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		SimpleDateFormat format1 = new SimpleDateFormat("yyyyMMddHHmmss");
		String newD = format1.format(dateTime);
		return newD;
	}

	/**
	 * 格式化日期yyyy-MM-dd HH:mm:ss
	 */
	public static String formatDateTime1(String date) {
		SimpleDateFormat df1 = new SimpleDateFormat("yyyyMMddHHmmss");
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date dateTime= null;
		try {
			 dateTime = df.parse(date);
		}catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return df1.format(dateTime);
	}
	 /**
	  *
	  * @Title: getMillis
	  * @Description: 返回当前毫秒
	  * @param date
	  * @return
	  */
	 public static long getMillis(Date date) {
	  Calendar c = Calendar.getInstance();
	  c.setTime(date);
	  return c.getTimeInMillis();
	 }

	 /**
	  * @Title: diffDate
	  * @Description: 两个日期相差几天
	  * @param dateStart
	  * @param dateEnd
	  * @return
	  */
	 public static int diffDate(Date dateStart, Date dateEnd) {
	  return (int) ((getMillis(dateStart) - getMillis(dateEnd)) / (24 * 3600 * 1000));
	 }
	 
	 /**
		 * 昨天
		 * @param c
		 * @return
		 */
		public static Calendar yesterday(Calendar c){
			long offset = 1*24*60*60*1000;
			Calendar calendar = null;
			if(c != null){
				calendar = c;
			}else{
				calendar = Calendar.getInstance();
			}
			
			calendar.setTimeInMillis(calendar.getTimeInMillis() - offset);
			return calendar;
		}
		
		/**
		 * 明天
		 * @param c
		 * @return
		 */
		public static Calendar tomorrow(Calendar c){
			long offset = 1*24*60*60*1000;
			Calendar calendar = null;
			if(c != null){
				calendar = c;
			}else{
				calendar = Calendar.getInstance();
			}
			
			calendar.setTimeInMillis(calendar.getTimeInMillis() + offset);
			return calendar;
		}

	public static boolean isValidDate(String str,String formatStr) {
		boolean convertSuccess=true;
		// 指定日期格式；
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		try {
			// 设置lenient为false. 否则SimpleDateFormat会比较宽松地验证日期，比如2007/02/29会被接受，并转换成2007/03/01
			format.setLenient(false);
			format.parse(str);
		} catch (ParseException e) {
			// 如果throw java.text.ParseException或者NullPointerException，就说明格式不对
			convertSuccess=false;
		}
		return convertSuccess;
	}

	/**
	 * 获取昨天开始时间
	 *
	 * shiliang 2019.10.28
	 */
	public static Date getLastDayStart(Date now) {
		Calendar c = Calendar.getInstance();
		c.setTime(now);
		int day = c.get(Calendar.DAY_OF_MONTH);
		c.set(Calendar.DAY_OF_MONTH, day - 1);
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		return c.getTime();
	}

	/**
	 * 获取昨天截止时间
	 *
	 * shiliang 2019.10.28
	 */
	public static Date getLastDayEnd(Date now) {
		Calendar c = Calendar.getInstance();
		c.setTime(now);
		int day = c.get(Calendar.DAY_OF_MONTH);
		c.set(Calendar.DAY_OF_MONTH, day - 1);
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		return c.getTime();
	}

	/**
	 *
	 * @Title: parseDate
	 * @Description: 把字符串解析为日期
	 * @param dateStr
	 * @param format
	 * @return Date
	 */
	public static Date parseDate(String dateStr, String format, Locale locale) {

		Date date = null;
		try {
			DateFormat df = new SimpleDateFormat(format, locale);
			date = df.parse(dateStr);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return date;
	}

	/**
	 *
	 * @return Date: yyyy-MM-dd HH:mm:ss
	 */
	public static String getCurrentDateStandardFormatString() {
		SimpleDateFormat format = new SimpleDateFormat(DEFAULT_TIME_FORMAT);
		return format.format(getCurrentDate());
	}

	/**
	 *
	 * @return Date: yyyyMMdd
	 */
	public static String getCurrentDateStandardFormatStr() {
		SimpleDateFormat format = new SimpleDateFormat(DEFAULT_TIME_FORMAT_YYYYMMDD);
		return format.format(getCurrentDate());
	}

	/**
	 * 比较时间大小
	 * @param date1
	 * @param date2
	 * @param pattern
	 * @return
	 */
	public static boolean compareDate(String date1, String date2, String pattern) {
		if (StringUtils.isBlank(pattern)) {
			pattern = DEFAULT_TIME_FORMAT_YYYYMMDD;
		}
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		try {
			Date parse = format.parse(date1);
			Date parse1 = format.parse(date2);
			if (parse.before(parse1)) {
				return true;
			}
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
		return false;
	}

	/*
	* 获取时分秒string类型
	* */
	public static String getTimeString(Date d) {
		System.out.println(d);
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		String dateNowStr = sdf.format(d);
		return dateNowStr;
	}

	/*
	* 根据日期，获取前几天或后几天
	* */
	public static String getDateInterval(Date date, int day){
		String formatDate = "";
		try {
			SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
			Calendar calendar = new GregorianCalendar();
			calendar.setTime(date);
			calendar.add(calendar.DATE,day);
			formatDate = sdf.format(calendar.getTime());
		}catch (Exception e){
			throw new RuntimeException(e);
		}

		return formatDate;
	}

}
